package com.cskaoyan.mall.pay.service.impl;

import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.order.dto.PayOrderSuccessRequest;
import com.cskaoyan.mall.order.dto.PayOrderSuccessResponse;
import com.cskaoyan.mall.order.service.PayOrderService;
import com.cskaoyan.mall.pay.api.OrderPayApi;
import com.cskaoyan.mall.pay.constants.PayResultEnum;
import com.cskaoyan.mall.pay.constants.PayReturnCodeEnum;
import com.cskaoyan.mall.pay.dal.entitys.Payment;
import com.cskaoyan.mall.pay.dal.persistence.PaymentMapper;
import com.cskaoyan.mall.pay.dto.PaymentRequest;
import com.cskaoyan.mall.pay.dto.alipay.AlipayQueryRetResponse;
import com.cskaoyan.mall.pay.dto.alipay.AlipaymentResponse;
import com.cskaoyan.mall.pay.service.PayCoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;

/**
 * @auther cskaoyan
 * @date 2022/5/21:11:44
 */
@Service
public class PayCoreServiceImpl implements PayCoreService {

    @Autowired
    PaymentMapper paymentMapper;

    @Autowired
    PayHelper payHelper;

    @Autowired
    OrderPayApi orderPayApi;

    /*
          获取支付二维码
     */
    @Override
    public AlipaymentResponse aliPay(PaymentRequest request) {

        AlipaymentResponse alipaymentResponse = new AlipaymentResponse();

        try {
            request.requestCheck();

            // 向只支付宝后台发起获取支付二维码请求
            String codeImgFileName = payHelper.test_trade_precreate(request);

            // 判断或支付二维码的结果

            // 如果失败
            if (codeImgFileName == null) {
                // 支付失败 返回响应    状态 GET_CODE_FALIED
                alipaymentResponse.setCode(PayReturnCodeEnum.GET_CODE_FALIED.getCode());
                alipaymentResponse.setMsg(PayReturnCodeEnum.GET_CODE_FALIED.getMsg());
                return alipaymentResponse;
            }

            // 如果成功
            alipaymentResponse.setQrCode(codeImgFileName);
            // 向tb_payment插入一条记录，记录待支付订单的支付信息  设置支付状态为TRADE_PROCESSING
            Payment payment = new Payment();
            payment.setId(null);
            payment.setStatus(PayResultEnum.TRADE_PROCESSING.getCode());
            payment.setOrderId(request.getTradeNo());
            // payment.setProductName();
            // payment.setPayNo();
            payment.setPayerUid(request.getUserId());
            // payment.setPayerName();
            payment.setPayerAmount(request.getTotalFee());
            payment.setOrderAmount(request.getOrderFee());
            payment.setPayWay(request.getPayChannel());
            // payment.setPaySuccessTime();
            // payment.setCompleteTime();
            // payment.setRemark();
            payment.setCreateTime(new Date());
            payment.setUpdateTime(new Date());
            int insertRows = paymentMapper.insert(payment);
            if (insertRows < 1) {
                throw new BizException(PayReturnCodeEnum.DB_EXCEPTION.getCode(), PayReturnCodeEnum.DB_EXCEPTION.getMsg());
            }

            alipaymentResponse.setCode(PayReturnCodeEnum.SUCCESS.getCode());
            alipaymentResponse.setMsg(PayReturnCodeEnum.SUCCESS.getMsg());
        } catch (BizException e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(alipaymentResponse, e);
        }

        // response 设置数据 codeImgFileName
        return alipaymentResponse;
    }

    /*
        获取订单支付结果
     */
    @Override
    public AlipayQueryRetResponse queryAlipayRet(PaymentRequest request) {

        AlipayQueryRetResponse response = new AlipayQueryRetResponse();
        try {
            request.requestCheck();
            boolean success = payHelper.test_trade_query(request);

            if (success) {
                // 1. 修改tb_payment中对应的订单支付状态 TRADE_SUCCESS， 支付成功时间等

                Payment payment = new Payment();
                payment.setStatus(PayResultEnum.TRADE_SUCCESS.getCode());
                payment.setPaySuccessTime(new Date());
                payment.setUpdateTime(new Date());
                Example example = new Example(Payment.class);
                example.createCriteria()
                        .andEqualTo("orderId", request.getTradeNo());
                int updateRows = paymentMapper.updateByExampleSelective(payment, example);
                if (updateRows < 1) {
                    throw new BizException(PayReturnCodeEnum.DB_EXCEPTION.getCode(), PayReturnCodeEnum.DB_EXCEPTION.getMsg());
                }
                // 调用订单服务完成     orderPayApi.payOrderSuccess()
                PayOrderSuccessRequest successRequest = new PayOrderSuccessRequest();
                successRequest.setOrderId(request.getTradeNo());
                successRequest.requestCheck();

                PayOrderSuccessResponse successResponse = orderPayApi.payOrderSuccess(successRequest);
                if (!successResponse.getCode().equals(PayReturnCodeEnum.SUCCESS.getCode())) {
                    throw new BizException(PayReturnCodeEnum.UPDATE_ORDERSTATUS_FAILED.getCode(), PayReturnCodeEnum.UPDATE_ORDERSTATUS_FAILED.getMsg());
                }
                // 2. 修改订单的状态 已支付状态
                // 3. 修改库存，根据订单id，查询出所有的订单商品条目，遍历订单商品条目，
                //    根据订单商品条目购买的数量，去扣减对应商品锁定库存的数量
                response.setCode(PayReturnCodeEnum.SUCCESS.getCode());
                response.setMsg(PayReturnCodeEnum.SUCCESS.getMsg());
            } else {
                // 修改tb_payment中对应的订单支付状态 FAIL， 支付成功时间等
                Payment payment = new Payment();
                payment.setStatus(PayResultEnum.FAIL.getCode());
                payment.setUpdateTime(new Date());
                Example example = new Example(Payment.class);
                example.createCriteria()
                        .andEqualTo("orderId", request.getTradeNo());
                int updateRows = paymentMapper.updateByExampleSelective(payment, example);
                if (updateRows < 1) {
                    throw new BizException(PayReturnCodeEnum.DB_EXCEPTION.getCode(), PayReturnCodeEnum.DB_EXCEPTION.getMsg());
                }
                response.setCode(PayReturnCodeEnum.PAYMENT_PROCESSOR_FAILED.getCode());
                response.setMsg(PayReturnCodeEnum.PAYMENT_PROCESSOR_FAILED.getMsg());
            }

        } catch (BizException e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }
}
